package com.hainingtong.user.handler;

import com.hainingtong.user.exception.TokenInvalidException;
import com.hainingtong.user.util.Result;
import com.hainingtong.user.util.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.Response;
import org.apache.shiro.authz.AuthorizationException;
import org.hibernate.validator.internal.engine.path.PathImpl;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result handle2(MethodArgumentNotValidException ex){
        BindingResult bindingResult = ex.getBindingResult();
        if(bindingResult.hasErrors()){
            FieldError fieldError = bindingResult.getFieldError();
            String field = fieldError.getField();
            String defaultMessage = fieldError.getDefaultMessage();
            log.error(ex.getMessage(),ex);
            Map<String,Object> ret = new HashMap<>();
            ret.put("field",field);
            ret.put("msg", defaultMessage);
            return Result.error(ResultCode.PARAM_ERROR, ret);
        }else {
            log.error(ex.getMessage(),ex);
            return Result.error(ResultCode.PARAM_ERROR);
        }
    }

    @ExceptionHandler(value = ConstraintViolationException.class)
    public Result handle1(ConstraintViolationException ex){
        StringBuilder msg = new StringBuilder();
        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
        for (ConstraintViolation<?> constraintViolation : constraintViolations) {
            PathImpl pathImpl = (PathImpl) constraintViolation.getPropertyPath();
            String paramName = pathImpl.getLeafNode().getName();
            String message = constraintViolation.getMessage();
            msg.append(paramName).append("[").append(message).append("]");
        }
        log.error(msg.toString(),ex);

        return Result.error(ResultCode.PARAM_ERROR, msg.toString());
    }

    @ExceptionHandler(value = {Exception.class})
    public Result handle1(Exception ex){
        log.error(ex.getMessage(),ex);
        return Result.error(ResultCode.UNKNOWN_REASON, ex.getMessage());
    }
}
